在實際開發中,一定會需要將資料持久化,常見的持久化技術有Spring 自帶的JdbcTemplate
、Spring Boot 提供的JPA
規範以及MyBatis
,這個系列文會逐一介紹上述三種持久化技術,本篇文章先講最簡單的JdbcTemplate
。
JDBC
,全名為Java Database Connectivity,是一種用於執行SQL 語法的Java API,它將資料庫存取SQL 語法與Java API 分開,讓開發人員開發資料庫應用程式更有彈性。
而JdbcTemplate
則是對JDBC
的封裝,目的是為了解決JDBC
每次使用都必須重新進行資料庫連接、處理SQL 語法、傳值、關閉資料庫連接等一系列操作所引發的一系列問題,替開發人員完成了所有JDBC 的底層工作,因此使用JdbcTemplate
就不用每次都進行連結、開啟、關閉等操作。
batchUpdate
: 批量更新。execute
: 執行SQL 語法。update
: 執行一條插入、更新或刪除語法。query
: 查詢並返回相應值。queryForList
: 查詢並返回一個List。queryForObject
: 查詢並返回一個Object。queryForMap
: 查詢並返回一個Map。queryForRowSet
: 查詢並返回一個RowSet。接下來會實作使用JdbcTemplate
對資料庫進行新增、查詢、修改等操作,由於修改跟刪除都是使用update
方法,這邊就不實作了,完整的程式碼就放在最下方的Github 連結。
<!-- MySQL Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- JDBC API -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
// 設定資料庫位址
spring.datasource.url=jdbc:mysql://localhost:3306/test_project?useUnicode=true&characeterEncoding=utf-8&serverTimezone=Asia/Shanghai
// 設定使用者資訊
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
CREATE TABLE IF NOT EXISTS member_account (
ID INT PRIMARY KEY AUTO_INCREMENT COMMENT "會員流水號",
USERNAME VARCHAR(60) UNIQUE NOT NULL COMMENT "帳號",
PASSWORD VARCHAR(60) NOT NULL COMMENT "密碼",
SALT VARCHAR(32) NOT NULL COMMENT "鹽值",
CREATE_BY VARCHAR(60) NOT NULL COMMENT "建立者",
CREATE_TIME DATETIME NOT NULL COMMENT "建立時間",
UPDATE_BY VARCHAR(60) NOT NULL COMMENT "修改者",
UPDATE_TIME DATETIME NOT NULL COMMENT "修改時間"
)DEFAULT CHARSET=utf8mb4
package com.example.demo.entity;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class MemberAccount extends Base {
private String id;
private String username;
private String password;
private String salt;
}
package com.example.demo.dao;
import com.example.demo.entity.MemberAccount;
public interface MemberAccountDao {
public Integer insert(MemberAccount memberAccount);
public MemberAccount findMemberAccountByUsername(String username);
public Integer update(MemberAccount memberAccount);
}
package com.example.demo.dao.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import com.example.demo.dao.MemberAccountDao;
import com.example.demo.entity.MemberAccount;
@Repository
public class MemberAccountDaoImpl implements MemberAccountDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private NamedParameterJdbcTemplate jdbcNameTemplate;
@Override
public Integer insert(MemberAccount memberAccount) {
// TODO Auto-generated method stub
String sql = " INSERT INTO test_project.member_account ( "
+ " USERNAME, PASSWORD, SALT, "
+ " CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME "
+ " ) "
+ " VALUE ( "
+ " :username, :password, :salt, "
+ " :create_by, NOW(), :update_by, NOW() "
+ " ) ";
SqlParameterSource paramSource = new BeanPropertySqlParameterSource(memberAccount);
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcNameTemplate.update(sql, paramSource, keyHolder);
return keyHolder.getKey().intValue();
}
@Override
public MemberAccount findMemberAccountByUsername(String username) {
// TODO Auto-generated method stub
String sql = " SELECT "
+ " ID, USERNAME, PASSWORD, SALT "
+ " FROM "
+ " test_project.member_account "
+ " WHERE "
+ " USERNAME = ? ";
List<MemberAccount> result = jdbcTemplate.query(sql, new BeanPropertyRowMapper<MemberAccount>(MemberAccount.class), new Object[] { username });
if(result != null && result.size() > 0) {
return result.get(0);
}
return null;
}
@Override
public Integer update(MemberAccount memberAccount) {
// TODO Auto-generated method stub
String sql = " UPDATE "
+ " test_project.member_account "
+ " SET "
+ " PASSWORD = :password, UPDATE_BY = :update_by, UPDATE_TIME = NOW() "
+ " WHERE "
+ " ID = :id ";
SqlParameterSource paramSource = new BeanPropertySqlParameterSource(memberAccount);
return jdbcNameTemplate.update(sql, paramSource);
}
}
package com.example.demo.dao;
import java.util.UUID;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.example.demo.entity.MemberAccount;
@SpringBootTest
public class MemberAccountDaoTest {
@Autowired
private MemberAccountDao memberAccountDao;
@Test
public void insert() {
MemberAccount memberAccount = new MemberAccount();
memberAccount.setUsername("username@email.com");
memberAccount.setPassword("password");
String salt = UUID.randomUUID().toString().toUpperCase().replaceAll("-", "");
memberAccount.setSalt(salt);
memberAccount.setCreate_by(memberAccount.getUsername());
memberAccount.setUpdate_by(memberAccount.getUsername());
Integer id = memberAccountDao.insert(memberAccount);
System.out.println(id);
}
@Test
public void findMemberAccountByUsername() {
String username = "username@email.com";
MemberAccount memberAccount = memberAccountDao.findMemberAccountByUsername(username);
if(memberAccount != null) System.out.println(memberAccount.toString());
}
@Test
public void update() {
MemberAccount memberAccount = new MemberAccount();
memberAccount.setId("1");
memberAccount.setPassword("123456");
memberAccount.setUpdate_by("username@email.com");
Integer result = memberAccountDao.update(memberAccount);
System.out.println(result);
}
}
(13) 甚麼是 JDBC、ORM、 JPA、ORM框架、Hibernate
JdbcTemplate (Spring Framework 5.3.10 API)